package com.yangzc.lion.sys.organization.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.yangzc.lion.common.model.BaseModel;
import com.yangzc.lion.sys.organization.constant.SysOrgConstant;
import com.yangzc.lion.sys.organization.interfaces.ISysOrgElement;
import com.yangzc.lion.sys.util.ModelUtil;
import com.yangzc.lion.sys.util.ObjectUtil;

/**
 * 组织架构元素
 * 
 * @author 叶中奇
 */
public class SysOrgElement extends BaseModel implements SysOrgConstant,
		ISysOrgElement {
	private static final long serialVersionUID = -7163022618192292476L;

	/*
	 * 类型
	 */
	private Integer fdOrgType;

	public Integer getFdOrgType() {
		return fdOrgType;
	}

	public void setFdOrgType(Integer fdOrgType) {
		this.fdOrgType = fdOrgType;
	}

	/*
	 * 层级ID
	 */
	protected String fdHierarchyId = SysOrgConstant.HIERARCHY_ID_SPLIT
			+ getFdId() + SysOrgConstant.HIERARCHY_ID_SPLIT;

	public String getFdHierarchyId() {
		return fdHierarchyId;
	}

	public void setFdHierarchyId(String fdHierarchyId) {
		this.fdHierarchyId = fdHierarchyId;
	}

	/*
	 * 名称
	 */
	private String fdName;

	public String getFdName() {
		return fdName;
	}

	public void setFdName(String fdName) {
		this.fdName = fdName;
	}

	/*
	 * 名称拼音
	 */
	private String fdNamePinYin;

	/*
	 * 编号
	 */
	private String fdNo;

	public String getFdNo() {
		return fdNo;
	}

	public void setFdNo(String fdNo) {
		this.fdNo = fdNo;
	}

	/*
	 * 排序号
	 */
	private Integer fdOrder;

	public Integer getFdOrder() {
		return fdOrder;
	}

	public void setFdOrder(Integer fdOrder) {
		this.fdOrder = fdOrder;
	}

	/*
	 * 关键字
	 */
	private String fdKeyword;

	public String getFdKeyword() {
		return fdKeyword;
	}

	public void setFdKeyword(String fdKeyword) {
		this.fdKeyword = fdKeyword;
	}

	/*
	 * 是否有效
	 */
	private Boolean fdIsAvailable;

	public Boolean getFdIsAvailable() {
		if (fdIsAvailable == null)
			fdIsAvailable = new Boolean(true);
		return fdIsAvailable;
	}

	public void setFdIsAvailable(Boolean fdIsAvailable) {
		this.fdIsAvailable = fdIsAvailable;
	}

	/*
	 * 是否业务相关
	 */
	private Boolean fdIsBusiness;

	public Boolean getFdIsBusiness() {
		if (fdIsBusiness == null)
			fdIsBusiness = new Boolean(true);
		return fdIsBusiness;
	}

	public void setFdIsBusiness(Boolean fdIsBusiness) {
		this.fdIsBusiness = fdIsBusiness;
	}

	/*
	 * 导入的数据的对应键值 update by wubing date:2006-12-14
	 */
	private String fdImportInfo;

	public String getFdImportInfo() {
		return fdImportInfo;
	}

	public void setFdImportInfo(String fdImportInfo) {
		this.fdImportInfo = fdImportInfo;
	}

	/*
	 * OMS导入时使用的字段，业务扩展时使用
	 */
	private String fdLdapDN;

	public String getFdLdapDN() {
		return fdLdapDN;
	}

	public void setFdLdapDN(String fdLdapDN) {
		this.fdLdapDN = fdLdapDN;
	}

	/*
	 * OMS导入时使用的字段，业务上务任何意义
	 */
	private Boolean fdFlagDeleted;

	public Boolean getFdFlagDeleted() {
		return fdFlagDeleted;
	}

	public void setFdFlagDeleted(Boolean fdFlagDeleted) {
		this.fdFlagDeleted = fdFlagDeleted;
	}

	/*
	 * 描述
	 */
	private String fdMemo;

	public String getFdMemo() {
		return fdMemo;
	}

	public void setFdMemo(String fdMemo) {
		this.fdMemo = fdMemo;
	}

	/*
	 * 创建时间
	 */
	private Date fdCreateTime = new Date();

	public Date getFdCreateTime() {
		return fdCreateTime;
	}

	public void setFdCreateTime(Date fdCreateTime) {
		this.fdCreateTime = fdCreateTime;
	}

	/*
	 * 最后修改时间
	 */
	private Date fdAlterTime = new Date();

	public Date getFdAlterTime() {
		return fdAlterTime;
	}

	public void setFdAlterTime(Date fdAlterTime) {
		this.fdAlterTime = fdAlterTime;
	}

	/*
	 * 本级领导
	 */
	private SysOrgElement fdThisLeader;

	public SysOrgElement getHbmThisLeader() {
		return fdThisLeader;
	}

	public void setHbmThisLeader(SysOrgElement fdThisLeader) {
		this.fdThisLeader = fdThisLeader;
	}

	private List fdThisLeaderChildren;

	public List getHbmThisLeaderChildren() {
		return fdThisLeaderChildren;
	}

	public void setHbmThisLeaderChildren(List fdThisLeaderChildren) {
		this.fdThisLeaderChildren = fdThisLeaderChildren;
	}

	/*
	 * 上级领导
	 */
	private SysOrgElement fdSuperLeader;

	public SysOrgElement getHbmSuperLeader() {
		return fdSuperLeader;
	}

	public void setHbmSuperLeader(SysOrgElement fdSuperLeader) {
		this.fdSuperLeader = fdSuperLeader;
	}

	private List fdSuperLeaderChildren;

	public List getHbmSuperLeaderChildren() {
		return fdSuperLeaderChildren;
	}

	public void setHbmSuperLeaderChildren(List fdSuperLeaderChildren) {
		this.fdSuperLeaderChildren = fdSuperLeaderChildren;
	}

	public SysOrgElement getLeader(int level) throws Exception {
		List<SysOrgElement> leaders = getAllLeader();
		if (level < 0)
			level = leaders.size() + level;
		if (level < 0 || level >= leaders.size())
			return null;
		return leaders.get(level);
	}

	public List<SysOrgElement> getAllLeader() throws Exception {
		// 以下代码由Domino的领导获取代码翻译而成，代码逻辑有些混乱，修改时需要跟domino的逻辑同步，否则很麻烦
		List<SysOrgElement> rtnVal = new ArrayList<SysOrgElement>();
		List<String> idList = new ArrayList<String>();
		List<String> nameList = new ArrayList<String>();
		SysOrgElement curElem = this; // 当前的组织架构元素
		SysOrgElement calElem = this; // 实际参与计算的组织架构元素
		SysOrgElement lastSuperLeader = null; // 上次循环使用的上级领导
		for (; curElem != null && calElem != null;) {
			// 若参与计算的组织架构是个人或已未定义领导的岗位，则计算的实体为所在的部门
			int curOrgType = calElem.getFdOrgType();
			if (curOrgType == ORG_TYPE_PERSON || curOrgType == ORG_TYPE_POST
					&& calElem.getHbmThisLeader() == null) {
				calElem = calElem.getFdParent();
				if (calElem == null) {
					break;
				}
			}
			// 死循环校验
			nameList.add(calElem.getFdName());
			if (idList.contains(calElem.getFdId())) {
				throw new RuntimeException("组织架构获取AllLeader死循环");
			}
			idList.add(calElem.getFdId());
			// 获取直接领导，若直接领导为空或跟上次循环使用的上级领导重叠了，则忽略
			SysOrgElement thisLeader = calElem.getHbmThisLeader();
			if (!(thisLeader == null || thisLeader.equals(lastSuperLeader))) {
				rtnVal.add(thisLeader);
			}
			if (calElem.getFdOrgType().intValue() == ORG_TYPE_ORG
					|| calElem.getFdOrgType().intValue() == ORG_TYPE_DEPT) {
				// 若计算对象为机构或部门，则获取上级领导，并添加到返回值列表中
				// 若上级领导不为空，则下次循环采用上级领导，否则采用上级部门
				lastSuperLeader = calElem.getHbmSuperLeader();
				if (lastSuperLeader != null) {
					rtnVal.add(lastSuperLeader);
					curElem = lastSuperLeader;
				} else {
					curElem = calElem.getFdParent();
				}
				calElem = curElem;
			} else {
				// 注意：这里计算对象只剩下岗位了
				if (thisLeader == null)
					break;
				// 设定下一轮循环的对象，这里的逻辑实在没有搞明白，但为了跟Domino一样，也只能照抄了
				// 疑惑点：在这里calElem与curElem居然不同步了，为什么判断用的是curOrgType，为什么要判断是否岗位，不解
				calElem = thisLeader;
				if (curOrgType == ORG_TYPE_POST) {
					curElem = calElem.getHbmThisLeader();
				} else {
					curElem = calElem.getFdParent();
				}
				lastSuperLeader = null;
			}
		}
		return rtnVal;
	}

	public SysOrgElement getMyLeader(int level) throws Exception {
		List<SysOrgElement> leaders = getAllMyLeader();
		if (level < 0)
			level = leaders.size() + level;
		if (level < 0 || level >= leaders.size())
			return null;
		return leaders.get(level);
	}

	public List<SysOrgElement> getAllMyLeader() throws Exception {
		List<SysOrgElement> rtnList = getAllLeader();
		if (getFdOrgType().intValue() == ORG_TYPE_POST) {
			rtnList.remove(this);
		} else if (getFdOrgType().intValue() == ORG_TYPE_PERSON) {
			rtnList.remove(this);
			rtnList.removeAll(getFdPosts());
		}
		return rtnList;
	}

	/*
	 * 父机构（此关系由计算得出，不提供set方法）
	 */
	public SysOrgElement getFdParentOrg() {
		return getHbmParentOrg();
	}

	public SysOrgElement getHbmParentOrg() {
		if (getFdOrgType().intValue() == ORG_TYPE_ORG)
			return null;
		SysOrgElement element = getFdParent();
		while (element != null
				&& element.getFdOrgType().intValue() > ORG_TYPE_ORG) {
			element = element.getFdParent();
		}
		return element;
	}

	public void setHbmParentOrg(SysOrgElement parentOrg) {

	}

	/*
	 * 父
	 */
	private SysOrgElement fdParent;

	public SysOrgElement getFdParent() {
		return getHbmParent();
	}

	public void setFdParent(SysOrgElement parent) {
		if (!ObjectUtil.equals(getHbmParent(), parent)) {
			ModelUtil.checkTreeCycle(this, parent, "fdParent");
			setHbmParent(parent);
		}
	}

	public SysOrgElement getHbmParent() {
		return fdParent;
	}

	public void setHbmParent(SysOrgElement parent) {
		this.fdParent = parent;
	}

	public String getFdParentsName() {
		return getFdParentsName(">>");
	}

	public String getFdParentsName(String splitStr) {
		String fdParentsName = "";
		List list = new ArrayList();
		if (fdParent != null) {
			try {
				SysOrgElement parent = (SysOrgElement) ModelUtil
						.clone(fdParent);
				while (parent != null) {
					list.add(parent);
					parent = parent.getFdParent();
				}
			} catch (Exception ex) {
			}
		}
		for (int i = list.size() - 1; i >= 0; i--) {
			fdParentsName += ((SysOrgElement) list.get(i)).getFdName();
			if (i > 0)
				fdParentsName += splitStr;
		}
		return fdParentsName;
	}

	/*
	 * 子（此关系由父维护，不提供set方法）
	 */
	private List fdChildren;

	public List getFdChildren() {
		List rtnVal = new ArrayList();
		if (getHbmChildren() != null)
			rtnVal.addAll(getHbmChildren());
		return rtnVal;
	}

	public List getHbmChildren() {
		return fdChildren;
	}

	public void setHbmChildren(List children) {
		this.fdChildren = children;
	}

	/*
	 * 所属群组
	 */
	private List fdGroups;

	public List getFdGroups() {
		List rtnVal = new ArrayList();
		if (getHbmGroups() != null)
			rtnVal.addAll(getHbmGroups());
		return rtnVal;
	}

	public void setFdGroups(List groups) {
		if (this.fdGroups == groups)
			return;
		if (this.fdGroups == null)
			this.fdGroups = new ArrayList();
		else
			this.fdGroups.clear();
		if (groups != null)
			this.fdGroups.addAll(groups);
	}

	public List getHbmGroups() {
		return fdGroups;
	}

	public void setHbmGroups(List groups) {
		this.fdGroups = groups;
	}

	/*
	 * 岗位列表（个人使用）
	 */
	private List fdPosts = null;

	public List getFdPosts() {
		List rtnVal = new ArrayList();
		if (getHbmPosts() != null)
			rtnVal.addAll(getHbmPosts());
		return rtnVal;
	}

	public void setFdPosts(List posts) {
		if (this.fdPosts == posts)
			return;
		if (this.fdPosts == null)
			this.fdPosts = new ArrayList();
		else
			this.fdPosts.clear();
		if (posts != null)
			this.fdPosts.addAll(posts);
	}

	public List getHbmPosts() {
		return fdPosts;
	}

	public void setHbmPosts(List posts) {
		this.fdPosts = posts;
	}

	/*
	 * 个人列表（岗位使用）
	 */
	public List fdPersons = null;

	public List getFdPersons() {
		List rtnVal = new ArrayList();
		if (getHbmPersons() != null)
			rtnVal.addAll(getHbmPersons());
		return rtnVal;
	}

	public void setFdPersons(List persons) {
		if (this.fdPersons == persons)
			return;
		if (this.fdPersons == null)
			this.fdPersons = new ArrayList();
		else
			this.fdPersons.clear();
		if (persons != null)
			this.fdPersons.addAll(persons);
	}

	public List getHbmPersons() {
		return fdPersons;
	}

	public void setHbmPersons(List persons) {
		this.fdPersons = persons;
	}

	@Override
	public boolean equals(Object object) {
		if (this == object)
			return true;
		if (object == null)
			return false;
		if (!(object instanceof SysOrgElement))
			return false;
		BaseModel objModel = (BaseModel) object;
		return ObjectUtil.equals(objModel.getFdId(), this.getFdId(), false);
	}

	/*
	 * 门户链接,部门,机构使用
	 */
	private String fdPortalLink;

	public String getFdPortalLink() {
		return fdPortalLink;
	}

	public void setFdPortalLink(String fdPortalLink) {
		this.fdPortalLink = fdPortalLink;
	}

	/*
	 * 门户名称
	 */
	private String fdPortalName;

	public String getFdPortalName() {
		return fdPortalName;
	}

	public void setFdPortalName(String fdPortalName) {
		this.fdPortalName = fdPortalName;
	}

	/*
	 * 是否已废弃,true表示禁用
	 */
	protected Boolean fdIsAbandon = new Boolean(false);

	public Boolean getFdIsAbandon() {
		return fdIsAbandon;
	}

	public void setFdIsAbandon(Boolean fdIsAbandon) {
		this.fdIsAbandon = fdIsAbandon;
	}

	/**
	 * @return fdNamePinYin
	 */
	public String getFdNamePinYin() {
		return fdNamePinYin;
	}

	/**
	 * @param fdNamePinYin
	 *            要设置的 fdNamePinYin
	 */
	public void setFdNamePinYin(String fdNamePinYin) {
		this.fdNamePinYin = fdNamePinYin;
	}
}
